import json
import jsonpath
import requests
from package.connector.sql_db import MySQL, Postgres, Oracle
from package.fastapi.encode import CustomJson


class CollectorTask:
    Category = None
    TOPIC = 'todo_parser_queue'

    def __init__(self, host=None, port=None):
        self.host = host
        self.port = port


class CollectorAPITask(CollectorTask):
    
    Category = 'api'

    """API 采集"""
    def __init__(self, method='get', url='', headers: dict=None, data=None, dynamic_auth=None, option=None, host=None, port=None):
        self.method = method
        self.url = url
        self.dynamic_auth = dynamic_auth
        self.data = data
        self.headers = headers
        self.params = {}
        self.option = option
        super().__init__(host=host, port=port)
    
    def _request(self, method, url, data, headers, params=None, **kwargs):
        """请求接口"""
        func = getattr(requests, method)
        if isinstance(data, (dict, list)):
            data = json.dumps(data, ensure_ascii=False)
        return func(url, params=params, data=data, headers=headers, verify=False, **kwargs)
    
    def _auth(self):
        if not self.dynamic_auth:
            return
        
        token_in = self.dynamic_auth['token_settings']['token_in']
        token_in_field = self.dynamic_auth['token_settings']['token_in_field']
        token_set = self.dynamic_auth['token_settings']['token_set']
        token_set_field = self.dynamic_auth['token_settings']['token_set_field']
        token_prefix = self.dynamic_auth['token_settings']['token_prefix']

        response = self._request(**self.dynamic_auth['request'])
        if token_in == 'headers':
            token = response.headers.get(token_in_field)
        else:
            token = jsonpath.jsonpath(response.json(), f'$.{token_in_field}')[0]  # jsonpath 取token

        if token_prefix:
            token = ' '.join([token_prefix, token])
        
        if token_set == 'headers':
            self.headers[token_set_field] = token
        elif token_set == 'params':
            self.params[token_set_field] = token
        else:
            self.data[token_set_field] = token

    def collector(self):
        """返回采集条数"""
        self._auth()
        response = self._request(self.method, self.url, self.data, self.headers)
        try:
            data = response.json()
            if self.option and self.option.get('field'):
                data = jsonpath.jsonpath(data, f'$.{self.field}')[0]
        except Exception as e:
            data = response.text
        return data
        

class CollectorDatabase(CollectorTask):
    Database = None

    def __init__(self, option, sql=None):
        self.sql = sql
        self.db = self.Database(**option)

    def collector(self):
        return json.loads(json.dumps(self.db.execute_sql(self.sql), cls=CustomJson))
    

class CollectorMysql(CollectorDatabase):
    """数据库采集"""
    Category = 'mysql'
    Database = MySQL

class CollectorPostgres(CollectorDatabase):
    """数据库采集"""
    Category = 'postgres'
    Database = Postgres

class CollectorOracle(CollectorDatabase):
    """数据库采集"""
    Category = 'oracle'
    Database = Oracle


CollectorTaskMap = {cls.Category: cls for cls in [*CollectorTask.__subclasses__(), *CollectorDatabase.__subclasses__()] if cls.Category}


if __name__ == '__main__':
    resp = CollectorAPITask(method='get', 
                             url='https://192.168.101.79/etl-control/api/v1.0/lgmp/translib/translib_all?order_key=translib_name&order_by=desc&page=1&page_size=10', 
                             data=None, 
                             headers={}, 
                             dynamic_auth=
                             {'request':{
                                 'method': 'post',
                                 'url': 'https://192.168.101.79/sysmgmt/api/v1/auth/login?dom_ctx=Default&app_context=_la&domain=default',
                                 'data': {"account":"admin","password":"g4OKSIp8QIcrKqoQqkFmkjyLu+lyMkhiLi4K9cHxnQ2DW7KDlFo58Z211P15y1F9Q4z9GEIS5Ume+GWwQo8w2aM6N0kPeP9NPXZ6Wr9uwzuqLz5+Xz1jMakW66rIbEZ0dGdJJQZX7YNQBiqOiR/nX79YEWHbXd8ip4FwQhxp4/w="},
                                 'headers': {"content-type": "application/json"} 
                             },
                             'token_settings': {
                                 'token_in': 'body',
                                 'token_in_field': 'access_token',
                                 'token_set': 'headers',
                                 'token_set_field': 'authorization',
                                 'token_prefix': 'Bearer'
                                 }
                             }
                             )
    r = resp.collector()
    print(r)

    d = CollectorPostgres(
        option=dict(
            host='192.168.101.79', 
            port=5432,
            username='aiops',
            password='aiops',
            database='aiops',
            query=None),
        sql='select * from operation_object'
        )
    print(d.collector())
